package com.example.base.utils;

import com.example.base.content.NumberContent;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.TextNode;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
public class RedisUtil {

    //工具类 统一使用单位分钟
    private static final TimeUnit DEF_UNIT = TimeUnit.MINUTES;

    @Setter
    private static RedisTemplate<String, JsonNode> redisTemplate;

    /**
     * 设置缓存有效期
     * @param key
     * @param value
     * @param timeout   超时时间 单位DEF_UNIT
     */
    public static void save(String key, String value, long timeout){
        //条件为空 缓存无意义
        if (StringUtils.isBlank(key) || StringUtils.isBlank(value) || timeout <= 0){
            return;
        }
        TextNode node = new TextNode(value);
        redisTemplate.opsForValue().set(key, node, timeout, DEF_UNIT);
    }

    /**
     * 根据key 删除缓存
     * @param key
     */
    public static Boolean delete(String key){
        if (StringUtils.isBlank(key)){
            return false;
        }
        return redisTemplate.delete(key);
    }

    /**
     * 获取key对应的value
     * @param key
     * @param clz
     * @return
     * @param <T>
     */
    public static <T>T getValue(String key, Class<T> clz){
        Boolean flag = redisTemplate.hasKey(key);
        if (Objects.isNull(flag)){
            return null;
        }
        //没有找到这个key
        if (!flag){
            return null;
        }
        JsonNode node = redisTemplate.opsForValue().get(key);
        if (Objects.isNull(node)){
            return null;
        }
        return JacksonUtil.toJavaType(node.toString(), clz);
    }

    /**
     * 判断key是否过期
     * @param key
     * @return
     */
    public static boolean expire(String key){
        if (StringUtils.isBlank(key)){
            return false;
        }
        //获取key的过期时间 单位为秒
        Long expire = redisTemplate.opsForValue().getOperations().getExpire(key, TimeUnit.MINUTES);
        if (Objects.isNull(expire)){
            return false;
        }
        return expire < NumberContent.ZERO;
    }

    /**
     * 刷新token 有效期
     * @param key
     * @param timeout
     */
    public static boolean refreshKey(String key, long timeout){
        Boolean flag = redisTemplate.expire(key, timeout, DEF_UNIT);
        return !Objects.isNull(flag) && flag;
    }
}
